package com.wyj.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.wyj.common.LogPortal;
import com.wyj.dto.data.HappyRankData;
import com.wyj.dto.data.HappyRankUserData;
import com.wyj.dto.data.UserGlobalData;
import com.wyj.dto.result.HappyRankResult;
import com.wyj.entity.ActivityConfig;
import com.wyj.entity.HappyRankInfo;
import com.wyj.enums.ActivityType;
import com.wyj.mapper.HappyRankInfoMapper;
import com.wyj.service.AbstractActivityService;
import com.wyj.service.HappyRankService;
import com.wyj.utils.DateUtil;
import com.wyj.utils.HappyRankTaskUtil;
import com.wyj.utils.SystemConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;

@Service
public class HappyRankServiceImpl extends AbstractActivityService implements HappyRankService {


    @Autowired
    HappyRankInfoMapper rankInfoMapper;

    @Autowired
    RedisTemplate redisTemplate;

    private static final int NUM_RANKS = 10; // 前后十名

    @Override
    public HappyRankResult getConfig(UserGlobalData globalData) {
        HappyRankData happyRank = globalData.getHappyRank();
        if (happyRank != null && happyRank.expireMills() <= 0) {
            refreshUserData(globalData);
        }
        ActivityConfig actConfig = getActConfig(ActivityType.HAPPY_RANK);
        if (actConfig != null) {
            if (happyRank == null || happyRank.expireMills() <= 0) {
                initData(actConfig, globalData);
            }
            return convertResult(globalData);
        }
        return null;
    }

    private void refreshUserData(UserGlobalData globalData) {
        //1.效验活动结束了吗
        BoundValueOperations valueOps = redisTemplate.boundValueOps(SystemConstants.HAPPY_RANK_EXPIRE + ActivityType.HAPPY_RANK.getName());
        if (valueOps == null) {
            return;
        }
        long expire = (long) valueOps.get();
        if (System.currentTimeMillis() <= expire) {
            return;
        }
        HappyRankData happyRank = globalData.getHappyRank();
        String rankKey = SystemConstants.HAPPY_RANK_PRE + happyRank.getStart();
        List<HappyRankUserData> rankUserDataList = Lists.newArrayList();
        // 获取玩家的排名
        Long rank = redisTemplate.boundZSetOps(rankKey).rank(globalData.getUuid());
        if (rank != null) {
            // 获取前后十名的成绩
            Long startRank = Math.max(rank - NUM_RANKS, 0);
            Long endRank = rank + NUM_RANKS;
            Set<ZSetOperations.TypedTuple<String>> rankSet = redisTemplate.boundZSetOps(rankKey).rangeWithScores(startRank, endRank);
            // 解析成员和分数
            for (ZSetOperations.TypedTuple<String> tuple : rankSet) {
                String uuid = tuple.getValue();
                double score = tuple.getScore();
                LambdaQueryWrapper<HappyRankInfo> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(HappyRankInfo::getUuid,uuid);
                HappyRankInfo happyRankInfo = rankInfoMapper.selectOne(queryWrapper);
                HappyRankUserData happyRankUserData = new HappyRankUserData();
                happyRankUserData.setName(uuid);
                happyRankUserData.setPoints((int) score);
                happyRankUserData.setCurMills(happyRankUserData.getCurMills());
                happyRankUserData.setLevel(happyRankUserData.getLevel());
                rankUserDataList.add(happyRankUserData);
            }
            // 按照要求进行排序
            sortUserList(rankUserDataList);

        }
        globalData.getHappyRank().setHappyRankUserList(rankUserDataList);
    }

    public void sortUserList(List<HappyRankUserData> userList) {
        Collections.sort(userList, new Comparator<HappyRankUserData>() {
            @Override
            public int compare(HappyRankUserData user1, HappyRankUserData user2) {
                // 按照规则进行比较
                if (user1.getPoints() != user2.getPoints()) {
                    return user2.getPoints() - user1.getPoints(); // 按points降序排列
                } else if (user1.getCurMills() != user2.getCurMills()) {
                    return  (int) (user1.getCurMills() - user2.getCurMills()); // 按curMills升序排列
                } else if (user1.getLevel() != user2.getLevel()) {
                    return (int) (user1.getLevel() - user2.getLevel()); // 按level升序排列
                } else {
                    return user1.getName().compareTo(user2.getName()); // 按name升序排列
                }
            }
        });
    }

    private HappyRankResult convertResult(UserGlobalData globalData) {
        return BeanUtil.copyProperties(globalData.getHappyRank(), HappyRankResult.class);
    }

    private void initData(ActivityConfig actConfig, UserGlobalData globalData) {
        HappyRankData happyRank = new HappyRankData();
        happyRank.setStart(actConfig.getStartTime());
        happyRank.setEnd(actConfig.getEndTime());
        happyRank.setExpire(DateUtil.getMills(actConfig.getEndTime(), DateUtil.TIME_FORMAT_COMMON));
        redisTemplate.boundValueOps(SystemConstants.HAPPY_RANK_EXPIRE + ActivityType.HAPPY_RANK.getName()).set(happyRank.getExpire());
        initRankInfo(globalData);
    }

    private void initRankInfo(UserGlobalData globalData) {
        String uuid = globalData.getUuid();
        HappyRankInfo happyRankInfo = new HappyRankInfo();
        happyRankInfo.setUuid(uuid);
        happyRankInfo.setPoints(0);
        happyRankInfo.setUpdateMills(System.currentTimeMillis());
        rankInfoMapper.insert(happyRankInfo);
    }

    @Override
    public void updateRankPoints(UserGlobalData globalData, int points) {
        HappyRankData happyRank = globalData.getHappyRank();
        if (happyRank == null || happyRank.expireMills() <= 0) {
            return;
        }
        HappyRankTaskUtil.submitTask(globalData.getUuid(), points);
    }

    @Transactional
    @Override
    public void createVoucherOrder(String uuid, int points) {
        LambdaQueryWrapper<HappyRankInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HappyRankInfo::getUuid, uuid);
        HappyRankInfo happyRankInfo = rankInfoMapper.selectOne(queryWrapper);
        if (happyRankInfo == null) {
            LogPortal.error(getClass().getSimpleName() + " not find this uuid={} rankInfo", uuid);
            return;
        }
        happyRankInfo.setPoints(happyRankInfo.getPoints() + points);
        happyRankInfo.setUpdateMills(System.currentTimeMillis());

        rankInfoMapper.updateById(happyRankInfo);
    }
}






















